/**
 * 组件规则的上下文
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2023/6/15
 */
import type { IChannelModelField } from '@/model'
import { uniqueId } from '@/utils'
import { reactive, ref } from 'vue'
import { getFormComponentRules } from '../lib/library'

const DEFAULT_LABEL_NAME = 'title'
const DEFAULT_FIELD_NAME = 'field'

export class context {
    public readonly id: string = uniqueId()
    public readonly type: string
    public key = ref(this.id)
    public label = ref()
    public filed: string = ''
    // 是否处于活动状态
    public active = ref<boolean>(false)
    // 表单数据格式
    public formData = reactive<Record<string, any>>({})

    // 上级
    public parent?: context

    // 孩子门
    public children: context[] = []

    constructor(type: string, label?: string) {
        this.type = type
        this.formData['type'] = type
        this.label.value = label
        if (label !== '') {
            this.filed = Math.random().toString(36).slice(3, 8)
        }
    }

    private upKey = () => (this.key.value = uniqueId())

    // 加载并解析请求结果
    public loadParserResults = (data: IChannelModelField) => {
        for (const key in data) {
            this.formData[key] = data[key]
            if (key === DEFAULT_LABEL_NAME) {
                this.label.value = data[key]
                continue
            }
            if (key === DEFAULT_FIELD_NAME) {
                this.filed = data[key]
            }
        }
    }

    // 设置组件活动状态
    public setActive = (active: boolean) => (this.active.value = active)

    // 插入指定位置
    public insert = (ctx: context, index: number) => {
        if (index === 0) {
            this.children.unshift(ctx)
        } else if (index === this.children.length) {
            this.children.push(ctx)
        } else {
            this.children.splice(index, 0, ctx)
        }
        this.upKey()
    }

    /**
     * 删除指定位置数据
     * @param id
     */
    public del = (id: string) => {
        for (let i = 0; i < this.children.length; i++) {
            if (this.children[i].id === id) {
                this.children.splice(i, 1)
                break
            }
        }
        this.upKey()
    }

    /**
     * 根据ID获取在子级中的位置
     * @param id
     */
    public getChildrenIndex = (id: string) => {
        for (let i = 0; i < this.children.length; i++) {
            if (this.children[i].id === id) {
                return i
            }
        }
    }

    public getChildren = () => {
        return this.children
    }

    /**
     * 向上移动
     * @param id
     */
    public moveUp = (id: string) => {
        for (let i = 0; i < this.children.length; i++) {
            if (i <= 0) continue
            if (this.children[i].id === id) {
                const temp = this.children[i]
                this.children[i] = this.children[i - 1]
                this.children[i - 1] = temp
                break
            }
        }
        this.upKey()
    }

    /**
     * 向下移动
     * @param id
     */
    public moveDown = (id: string) => {
        for (let i = 0; i < this.children.length; i++) {
            if (i + 1 >= this.children.length) break
            if (this.children[i].id === id) {
                const temp = this.children[i]
                this.children[i] = this.children[i + 1]
                this.children[i + 1] = temp
                break
            }
        }
        this.upKey()
    }

    /**
     * 设置表单的值
     * @param field
     * @param value
     */
    public setFormValue = (field: string, value: any) => {
        if (field === DEFAULT_FIELD_NAME) {
            this.filed = value
        } else if (field === DEFAULT_LABEL_NAME) {
            this.label.value = value
        }
        this.formData[field] = value
    }

    /**
     * 获取组件的表单构建规则
     */
    public getFormRules = () => {
        const rules = JSON.parse(JSON.stringify(getFormComponentRules(this.type)))
        const rule = []
        for (const item of rules) {
            if (item.field === DEFAULT_FIELD_NAME) {
                item.value = this.filed
                this.setFormValue(DEFAULT_FIELD_NAME, item.value)
            } else if (item.field === DEFAULT_LABEL_NAME) {
                item.value = this.label.value
                this.setFormValue(DEFAULT_LABEL_NAME, item.value)
            } else if (item.field !== undefined) {
                if (this.formData[item.field] !== undefined) {
                    item.value = this.formData[item.field]
                } else {
                    this.formData[item.field] = item?.value
                    this.setFormValue(item.field, item.value)
                }
            }

            rule.push(item)
        }

        return rule
    }

    // 交换位置
    public swap = (newIndex: number, oldIndex: number) => {
        const temp = this.children[oldIndex]
        this.children.splice(oldIndex, 1)
        this.children.splice(newIndex, 0, temp)
    }
}
